package com.ysstech.reportworld.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ysstech.common.annotation.YssLog;
import com.ysstech.common.annotation.YssPermissions;
import com.ysstech.common.controller.BaseController;
import com.ysstech.common.entity.Dicvalue;
import com.ysstech.common.entity.SheetDTO;
import com.ysstech.common.entity.TreeNode;
import com.ysstech.common.exception.BusinessException;
import com.ysstech.common.util.fileutil.FileWriterUtil;
import com.ysstech.common.util.resultutil.RestResult;
import com.ysstech.common.util.resultutil.ResultGenerator;
import com.ysstech.reportworld.entity.DemandBugInfo;
import com.ysstech.reportworld.entity.Table;
import com.ysstech.reportworld.entity.TableDetail;
import com.ysstech.reportworld.entity.TpGlExhibDatadict;
import com.ysstech.reportworld.enums.ReportWorldEnum;
import com.ysstech.reportworld.enums.ReportWorldFileNameEnum;
import com.ysstech.reportworld.service.*;
import com.ysstech.reportworld.service.CustomerService;
import com.ysstech.reportworld.service.TpGlExhibDatadictService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 报表表结构管理前端控制器
 * </p>
 *
 * @author lishuangliang
 * @since 2022-04-26
 */
@Controller
@Slf4j
@Api(tags = "报表世界表结构管理api")
@RequestMapping("/table")
public class TableController extends BaseController {

    @Autowired
    private TableService tableService;
    @Autowired
    private TableDetailService tableDetailService;
    @Autowired
    private ModularService modularService;
    @Autowired
    private CustomerService customerService;
    @Autowired
    private ReportService reportService;
    // 基础数据的字典信息
    @Autowired
    private TpGlExhibDatadictService tpGlExhibDatadictService;
    @Autowired
    private DemandBugInfoService demandBugInfoService;

    @YssPermissions(value = {"reportworld:table"})
    @ApiOperation(value = "跳转报表世界表结构管理页面")
    @YssLog(module = "报表世界表结构管理", remark = "跳转报表世界表结构管理页面")
    @RequestMapping(value = "/page")
    public String page() throws Exception {
        return "reportworld/table";
    }

    @YssPermissions(value = {"reportworld:table"})
    @ApiOperation(value = "获取报表世界表结构管理页面初始值")
    @YssLog(module = "报表世界表结构管理", remark = "获取报表世界表结构管理页面初始值")
    @PostMapping(value = "/init")
    @ResponseBody
    public RestResult init() throws Exception {
        Map<String, Object> map = new HashMap<>();
        //字段类型
        List<Dicvalue> listColumnType = dicValueService.getCacheDicValueList(ReportWorldEnum.COLUMN_TYPE.getCode());
        map.put("listColumnType", listColumnType);
        // 报表世界所在分层
        List<Dicvalue> listLayered = dicValueService.getCacheDicValueList(ReportWorldEnum.REPORT_TABLE_LAYERED.getCode());
        map.put("listLayered", listLayered);
        map.put("listLayered2", listLayered);
        // 状态
        List<Dicvalue> listStatus = dicValueService.getCacheDicValueList(ReportWorldEnum.REPORT_STATUS.getCode());
        map.put("listStatus", listStatus);
        map.put("listStatus2", listStatus);
        // 所属模块
        List<TreeNode> listModular = modularService.queryModularTree();
        map.put("listModular", listModular);
        // 字段所属客户
        List<TreeNode> listCustomer = customerService.queryCustomerTree();
        map.put("listCustomer", listCustomer);
        // 字段所属报表
        List<TreeNode> listReport = reportService.queryReportTree();
        map.put("listReport", listReport);
        // 版本
        List<Dicvalue> listVersion = dicValueService.getCacheDicValueList(ReportWorldEnum.REPORT_VERSION.getCode());
        map.put("listVersion", listVersion);
        map.put("listVersion2", listVersion);
        // 表类型
        List<Dicvalue> listFtype = dicValueService.getCacheDicValueList(ReportWorldEnum.REPORT_TABLE_FTYPE.getCode());
        map.put("listFtype", listFtype);
        map.put("listFtype2", listFtype);
        // 表来源
        List<Dicvalue> listFsource = dicValueService.getCacheDicValueList(ReportWorldEnum.REPORT_TABLE_FSOURCE.getCode());
        map.put("listFsource", listFsource);
        map.put("listFsource2", listFsource);
        // 查询所有字典项信息的语句
        QueryWrapper<TpGlExhibDatadict> wrapper = new QueryWrapper<>();
        wrapper.select("CLASS_ID,CLASS_NAME");
        wrapper.groupBy("CLASS_ID");
        wrapper.orderByAsc("CLASS_ID");
        List<TpGlExhibDatadict> listTpGlExhibDatadict = tpGlExhibDatadictService.list(wrapper);
        if (!CollectionUtils.isEmpty(listTpGlExhibDatadict)) {
            for (TpGlExhibDatadict tpGlExhibDatadict : listTpGlExhibDatadict) {
                if (null == tpGlExhibDatadict) {
                    continue;
                }
                tpGlExhibDatadict.setClassName(tpGlExhibDatadict.getClassId() + "-" + tpGlExhibDatadict.getClassName());
            }
        }
        map.put("listTpGlExhibDatadict", listTpGlExhibDatadict);
        //获取所有表信息，选择关联表的时候
        QueryWrapper<Table> wrapper2 = new QueryWrapper<>();
        List<Table> tables = tableService.list(wrapper2);
        if (!CollectionUtils.isEmpty(tables)) {
            for (Table table : tables) {
                if (null == table) {
                    continue;
                }
                table.setChineseName(table.getName() + "-" + table.getChineseName());
            }
        }
        map.put("reportTables", tables);
        map.put("reportTables2", tables);
        //字段类型
        List<Dicvalue> listIndexedType = dicValueService.getCacheDicValueList(ReportWorldEnum.REPORT_TABLE_INDEXED.getCode());
        map.put("listIndexedType", listIndexedType);
        // 数据库类型
        List<Dicvalue> listReportDataBaseType = dicValueService.getCacheDicValueList(ReportWorldEnum.REPORT_DATABASE_TYPE.getCode());
        if (!CollectionUtils.isEmpty(listReportDataBaseType)) {
            for (int i = listReportDataBaseType.size() - 1; i >= 0; i--) {
                Dicvalue result = listReportDataBaseType.get(i);
                if ("COMMON".equals(result.getValue())) {
                    listReportDataBaseType.remove(result);
                    break;
                }
            }
            map.put("listReportDataBaseType", listReportDataBaseType);
        }
        // 当前版本的所有需求和BUG
        List<DemandBugInfo> demandBugInfoList = demandBugInfoService.selectByPrimaryByVersion();
        map.put("demandBugInfoList", demandBugInfoList);
        return ResultGenerator.getSuccessResult("获取页面初始化信息成功", map);
    }


    @YssPermissions(value = {"reportworld:table"})
    @YssLog(module = "报表世界表结构管理", remark = "查询报表世界表结构数据")
    @ApiOperation(value = "查询报表世界表结构数据")
    @RequestMapping(value = "/listTable")
    @ResponseBody
    public RestResult listTable(Table table, String page, String rows) throws Exception {
        return ResultGenerator.getSuccessResult("查询报表世界表结构数据成功",
                tableService.queryAllReport(table, this.getPage(page, rows)));
    }


    @YssPermissions(value = {"reportworld:table"})
    @YssLog(module = "报表世界表结构管理", remark = "查询报表世界表结构明细数据")
    @ApiOperation(value = "查询报表世界表结构明细数据")
    @RequestMapping(value = "/queryTableDetailListByTableId")
    @ResponseBody
    public RestResult queryTableDetailListByTableId(TableDetail tableDetail) throws Exception {
        return ResultGenerator.getSuccessResult("查询报表世界表结构明细数据成功",
                tableDetailService.queryTableDetailListByTableId(tableDetail));
    }


    @YssPermissions(value = {"reportworld:table"})
    @YssLog(module = "报表世界表结构管理", remark = "查询报表世界表结构明细数据")
    @ApiOperation(value = "查询报表世界表结构明细数据")
    @RequestMapping(value = "/queryTableDetailListByTableName")
    @ResponseBody
    public RestResult queryTableDetailListByTableName(Table reportWorldTable) throws Exception {
        if (null == reportWorldTable || (StringUtils.isBlank(reportWorldTable.getName()) && StringUtils.isBlank(reportWorldTable.getId()))) {
            throw new BusinessException("获取报表世界表结构信息失败，请稍后重试！");
        }
        QueryWrapper<Table> wrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(reportWorldTable.getName())) {
            wrapper.eq("NAME", reportWorldTable.getName());
        }
        if (StringUtils.isNotBlank(reportWorldTable.getId())) {
            wrapper.eq("ID", reportWorldTable.getId());
        }
        Table table = tableService.getOne(wrapper);
        if (null == table) {
            throw new BusinessException("获取报表世界表结构信息失败，请稍后重试！");
        }
        TableDetail tableDetail = new TableDetail();
        tableDetail.setTableId(table.getId());
        List<TableDetail> list = tableDetailService.queryTableDetailListByTableId(tableDetail);
        if (!CollectionUtils.isEmpty(list)) {
            for (TableDetail detail : list) {
                if (null == detail) {
                    continue;
                }
                detail.setColumnChineseName(detail.getColumnName() + "-" + detail.getColumnChineseName());
            }
        }
        return ResultGenerator.getSuccessResult("查询报表世界表结构明细数据成功", list);
    }


    @YssPermissions(value = {"reportworld:table:add"})
    @YssLog(module = "报表世界表结构管理", remark = "添加表结构信息")
    @ApiOperation(value = "添加表结构信息")
    @RequestMapping(value = "/add")
    @ResponseBody
    public RestResult add(Table table) throws Exception {
        if (null == table) {
            throw new BusinessException("获取新增报表世界表结构信息失败，请稍后重试！");
        }
        table.setAddUser(redisCacheManager.getLoginUserInfo().getLoginId());
        table.setAddTime(LocalDateTime.now());
        tableService.addReportTable(table);
        return ResultGenerator.getSuccessResult("添加表结构明细信息成功");
    }


    @YssPermissions(value = {"reportworld:table:edit"})
    @YssLog(module = "报表世界表结构管理", remark = "修改报表世界表结构信息")
    @ApiOperation(value = "修改表结构信息")
    @RequestMapping(value = "/edit")
    @ResponseBody
    public RestResult edit(Table table) throws Exception {
        if (null == table) {
            throw new BusinessException("获取删除报表世界表结构信息失败，请稍后重试！");
        }
        table.setEditUser(redisCacheManager.getLoginUserInfo().getLoginId());
        table.setEditTime(LocalDateTime.now());
        tableService.updateReportTable(table);
        return ResultGenerator.getSuccessResult("修改表结构信息成功");
    }

    @YssPermissions(value = {"reportworld:table:del"})
    @YssLog(module = "报表世界表结构管理", remark = "删除报表世界表结构信息")
    @ApiOperation(value = "删除报表世界表结构数据")
    @RequestMapping(value = "/del")
    @ResponseBody
    public RestResult del(String id) throws Exception {
        tableService.deleteReportTable(id);
        return ResultGenerator.getSuccessResult("删除报表世界表结构信息成功");
    }

    /**
     * 批量修改表信息
     *
     * @return
     */
    @YssPermissions(value = {"reportworld:table:batchUpdate"})
    @ApiOperation(value = "批量修改表信息")
    @YssLog(module = "表结构管理", remark = "批量修改表信息")
    @RequestMapping(value = "/batchUpdateTableInfo")
    @ResponseBody
    public RestResult batchUpdateTableInfo(Table table, String ids) throws Exception {
        tableService.batchUpdateTableInfo(table, ids);
        return ResultGenerator.getSuccessResult("批量修改表信息成功！");
    }

    /**
     * 判断用表名称是否已经存在
     *
     * @param newName
     * @return
     */
    @ApiOperation(value = "检查表名是否存在")
    @YssLog(module = "报表世界表结构管理", remark = "检查表名是否存在")
    @RequestMapping(value = "/checkTableName")
    @ResponseBody
    public RestResult checkTableName(String newName) {
        if (StringUtils.isBlank(newName)) {
            return ResultGenerator.getFailResult("检查用表信息失败，请稍后重试！");
        }
        QueryWrapper<Table> wrapper = new QueryWrapper<>();
        wrapper.eq("NAME", newName.toUpperCase());
        int count = tableService.count(wrapper);
        //查询是否存在code值得参数
        if (count > 0) {//返回true表示已经存在
            return ResultGenerator.getSuccessResult("检查表名信息成功", false);
        } else {
            return ResultGenerator.getSuccessResult("检查表名信息成功", true);
        }
    }

    /**
     * 读取表信息
     *
     * @return
     */
    @YssPermissions(value = {"reportworld:table:read"})
    @ApiOperation(value = "获取报表世界数据到库里")
    @YssLog(module = "报表管理", remark = "获取报表世界数据到库里")
    @RequestMapping(value = "/readTableInfo")
    @ResponseBody
    public RestResult readTableInfo(String tableName) throws Exception {
        tableService.readTableInfo(tableName);
        return ResultGenerator.getSuccessResult("获取报表世界数据到库里成功！");
    }

    /**
     * 读取表信息文档数据到数据库
     *
     * @return
     */
    @YssPermissions(value = {"reportworld:table:readFile"})
    @ApiOperation(value = "获取报表世界数据到库里")
    @YssLog(module = "报表管理", remark = "获取报表世界数据到库里")
    @RequestMapping(value = "/getTableInfoExecl")
    @ResponseBody
    public RestResult getTableInfoExecl(MultipartFile multipartfile) throws Exception {
        if (null == multipartfile) {
            throw new BusinessException("没有获取到文件，请稍后重试！");
        }
        return ResultGenerator.getSuccessResult("读取数据成功！", tableService.getTableInfoExecl(multipartfile));
    }

    /**
     * 导出execl文件
     *
     * @return
     */
    @YssPermissions(value = {"reportworld:table:execl"})
    @ApiOperation(value = "导出表结构信息")
    @YssLog(module = "表结构管理", remark = "导出表结构信息")
    @RequestMapping(value = "/tableExecl")
    @ResponseBody
    public void tableExecl(HttpServletResponse response, String ids) throws Exception {
        List<SheetDTO> sheetList = tableService.tableExeclList(ids);
        FileWriterUtil.exportExcel(response, sheetList, ReportWorldFileNameEnum.REPORT_TABLE_FILENAME_XLSX.getCode(),
                ReportWorldFileNameEnum.REPORT_TABLE_FILENAME_XLSX.getDesc());
    }

    /**
     * 导出建表语句文件
     *
     * @return
     */
    @YssPermissions(value = {"reportworld:table:create"})
    @ApiOperation(value = "导出表结构信息")
    @YssLog(module = "表结构管理", remark = "导出表结构信息")
    @RequestMapping(value = "/tableCreate")
    @ResponseBody
    public void tableCreate(HttpServletResponse response, String ids, String ftype) throws Exception {
        String json = tableService.tableCreateJsonInfo(ids, ftype);
        FileWriterUtil.downloadFileBuffer(response, json, ReportWorldFileNameEnum.REPORT_TABLE_FILENAME_SQL.getCode(),
                ReportWorldFileNameEnum.REPORT_TABLE_FILENAME_SQL.getDesc());
    }


    /**
     * 查看表变更信息
     *
     * @return
     */
    @YssPermissions(value = {"reportworld:table:viewUpgrade"})
    @ApiOperation(value = "查看表变更信息")
    @YssLog(module = "表结构管理", remark = "查看表变更信息")
    @RequestMapping(value = "/viewUpgradeTableInfo")
    @ResponseBody
    public RestResult viewUpgradeTableInfo(String ids) throws Exception {
        Map<String, String> map = tableService.viewUpgradeTableInfo(ids);
        return ResultGenerator.getSuccessResult("查看表变更信息成功！", map);
    }

    /**
     * 和文件里的表对比差异
     *
     * @return
     */
    @YssPermissions(value = {"reportworld:table:magerFile"})
    @ApiOperation(value = "和文件里的表对比差异")
    @YssLog(module = "报表管理", remark = "和文件里的表对比差异")
    @RequestMapping(value = "/magerTableByFile")
    @ResponseBody
    public RestResult magerTableByFile(MultipartFile multipartfile) throws Exception {
        if (null == multipartfile) {
            throw new BusinessException("没有获取到文件，请稍后重试！");
        }
        return ResultGenerator.getSuccessResult("读取数据成功！", tableService.magerTableByFile(multipartfile));
    }

    /**
     * 读取需求设计文档  同步字典字段和业务主键
     *
     * @return
     */
    @YssPermissions(value = {"reportworld:table:demanddesign"})
    @ApiOperation(value = "获取报表世界数据到库里")
    @YssLog(module = "报表管理", remark = "获取报表世界数据到库里")
    @RequestMapping(value = "/readDemandDesign")
    @ResponseBody
    public RestResult readDemandDesign(MultipartFile multipartfile) throws Exception {
        if (null == multipartfile) {
            throw new BusinessException("没有获取到文件，请稍后重试！");
        }
        return ResultGenerator.getSuccessResult("读取数据成功！", tableService.readDemandDesign(multipartfile));
    }
}
